さまざまな方法でEC2に接続して、各接続方法ごとにCloudTrailのイベント履歴やイベントレコードを比較してみた
はじめに
こんにちは、おのやんです。
みなさん、EC2インスタンスへ接続した際に、接続方法によってどんなイベント履歴が取れるのか気になりませんか?私はものすごぉ〜く気になります。
EC2に接続した際に発火するイベントや、イベント履歴に書かれている内容を把握しておくと、EC2が不具合などを起こした時に調査する手掛かりとして使えます。ということで、今回はEC2への各種接続方法ごとに、CloudTrailのイベント履歴やイベントレコードをまとめたいと思います。
今回検証する接続方法
今回は、EC2インスタンスのOS、操作対象、接続方法の3つの条件を変えて、それぞれ検証していきます。
なお、今回はLinuxインスタンスのAMIはAmazon Linux 2023 AMI 2023.1.20230825.0 x86_64 HVM kernel-6.1
、
Windows ServerのAMIはMicrosoft Windows Server 2022 Full Locale English AMI provided by Amazon
となっています。
今回検証したEC2インスタンスOSと接続方法は、それぞれ以下の通りです。
番号 | EC2インスタンスのOS | 操作対象 | 接続方法 |
---|---|---|---|
1 | Linux | ローカルPC | SSH接続 |
2 | Linux | マネジメントコンソール | Session Manager |
3 | Linux | マネジメントコンソール | Instance Connect(Endpointなし) |
4 | Linux | マネジメントコンソール | Instance Connect(Endpointあり) |
5 | Linux | AWS CLI | Session Manager |
6 | Linux | AWS CLI | instance Connect(Endpointなし) |
7 | Linux | AWS CLI | instance Connect(Endpointあり) |
8 | Windows | マネジメントコンソール | Session Manager |
9 | Windows | マネジメントコンソール | Fleet Manager |
10 | Windows | AWS CLI | Instance Connect |
CloudTrailイベント履歴の取得方法
今回は、PythonのライブラリであるBoto3でコードを実行します。正常に処理が実行されれば、そのレスポンスとして辞書型データに加工されたイベント履歴が返ってきます。
なお、条件によってはEC2インスタンスを変えているので、ec2_instance_id
は都度適切な値に書き直す必要があります。また、AWS CLIのプロファイル情報は適切に設定できているものとします。
import boto3 ec2_instance_id = "i-0f..." aws_region = "ap-northeast-1" session = boto3.Session(profile_name="get-event-history", region_name=aws_region) cloudtrail_client = session.client("cloudtrail") response = cloudtrail_client.lookup_events( LookupAttributes=[ {"AttributeKey": "ReadOnly", "AttributeValue": "false"}, ], MaxResults=10, ) events = response.get("Events", []) for event in events: print(event) print("\n")
なお、実際にこちらのコードを実行した場合には、複数のイベント履歴がダァーーっと表示されます。そのため、EC2インスタンス接続時のイベントをまとめる際には、コードを複数回実行して接続時刻とイベント発火時刻が同じものを選定しています。
CloudTrailイベント履歴の取得方法に関する詳しい内容はこちらにまとめました。よければ参考にしてください。
1. LinuxインスタンスにローカルPCからSSH接続する場合
LinuxインスタンスにローカルPCからSSH接続する場合、CloudTrailのイベント履歴には記録されません。なぜなら、SSH接続はAWSのAPIとは関係ないからです。
何回かBoto3のコードを実行したのですが、SSH接続したタイミングに記録されたイベントは見られませんでした。マネジメントコンソール上でもイベントは記録されませんでした。
こちらは、AWSのドキュメントを見てもらえれば分かると思います。
これらのイベントは、AWS Management Console、AWS Command Line Interface、AWS の SDK および API を通じて行われたアクティビティをキャプチャします。
自明なことではありますが、LinuxインスタンスにSSH接続するのはAWS固有の操作ではありません。そのためCloudTrailの履歴にも記録されません。
2. Linuxインスタンスにマネジメントコンソール上のSession Managerで接続する場合
Linuxインスタンスにマネジメントコンソール上のSession Managerで接続した場合、CloudTrailイベント履歴からは StartSession イベントが取得されます。
StartSessionイベントに関しては、APIのリファレンスに記述があります。
Initiates a connection to a target (for example, a managed node) for a Session Manager session. Returns a URL and token that can be used to open a WebSocket connection for sending input and receiving outputs.
セッションマネージャーセッションのターゲット(管理ノードなど)への接続を開始します。入力の送信と出力の受信のために WebSocket 接続を開くために使用できる URL とトークンを返します。(DeepLにて翻訳)
ここでいうターゲットとはEC2インスタンスのことですね。マネジメントコンソール上のSession Managerが、EC2インスタンスへ接続を開始する時に実行されるAPIのようです。
イベント履歴は、Pythonの辞書型データに加工されて取得できます。イベントに関する情報が記述されているほか、実行したユーザーなども読み取れます。
{ "EventId": "b243ee4a-...", "EventName": "StartSession", "ReadOnly": "false", "AccessKeyId": "ASIA...", "EventTime": datetime.datetime(2023,9,4,14,56,4, tzinfo=tzlocal()), "EventSource": "ssm.amazonaws.com", "Username": "cm...", "Resources": [], "CloudTrailEvent": { "eventVersion": "1.08", "userIdentity": { "type": "AssumedRole", "principalId": "AROA...", "arn": "arn:aws:sts: : 1234...:assumed-role/cm...", "accountId": "1234...", "accessKeyId": "ASIA...", "sessionContext": { "sessionIssuer": { "type": "Role", "principalId": "AROA...", "arn": "arn:aws:iam: : 1234...:role/cm...", "accountId": "1234...", "userName": "cm..." }, "attributes": { "creationDate": "2023-09-04T05: 54: 51Z", "mfaAuthenticated": "true" } } }, "eventTime": "2023-09-04T05: 56: 04Z", "eventSource": "ssm.amazonaws.com", "eventName": "StartSession", "awsRegion": "ap-northeast-1", "sourceIPAddress": "10...", "userAgent": "AWS Internal", "requestParameters": { "target": "i-02..." }, "responseElements": { "sessionId": "cm...", "tokenValue": "Value hidden due to security reasons.", "streamUrl": "wss: //ssmmessages.ap-northeast-1.amazonaws.com/v1/data-channel..." }, "requestID": "a27d...", "eventID": "b243...", "readOnly": false, "eventType": "AwsApiCall", "managementEvent": true, "recipientAccountId": "1234...", "eventCategory": "Management", "sessionCredentialFromConsole": "true" } }
3. Linuxインスタンスにマネジメントコンソール上のEC2 Instance Connect(Endpointなし)で接続する場合
Linuxインスタンスにマネジメントコンソール上のEC2 Instance Connectで接続した場合、CloudTrailイベント履歴には SendSSHPublicKey イベントが記録されます。
EC2 Instance Connectは、内部でSSH接続を利用しています。具体的には、Instance Connect APIからSSHのパブリックキーがインスタンスメタデータに送信されます。
Amazon EC2 Instance Connect は、Secure Shell (SSH) を使用して Linux インスタンスに接続するシンプルで安全な方法を提供します。
EC2 Instance Connect を使用してインスタンスに接続すると、Instance Connect API から SSH パブリックキーがインスタンスメタデータにプッシュされ、60 秒間保持されます。
こちらの動作が、CloudTrailイベント履歴にも記録されたということですね。
イベント履歴は、Pythonの辞書型データに加工されて取得できます。ローカルのSSH公開鍵を、EC2インスタンスに送信していることがわかりますね。
{ "EventId": "cdc5...", "EventName": "SendSSHPublicKey", "ReadOnly": "false", "AccessKeyId": "ASIA...", "EventTime": datetime.datetime(2023,9,6,10,53,19, tzinfo=tzlocal()), "EventSource": "ec2-instance-connect.amazonaws.com", "Username": "cm...", "Resources": [ { "ResourceType": "AWS::EC2::Instance", "ResourceName": "i-02..." } ], "CloudTrailEvent": { "eventVersion": "1.08", "userIdentity": { "type": "AssumedRole", "principalId": "AROA...", "arn": "arn:aws:sts: : 1234...:assumed-role/cm..", "accountId": "1234...", "accessKeyId": "ASIA...", "sessionContext": { "sessionIssuer": { "type": "Role", "principalId": "AROA...", "arn": "arn:aws:iam: : 1234...:role/cm...", "accountId": "1234...", "userName": "cm..." }, "webIdFederationData": {}, "attributes": { "creationDate": "2023-09-06T01: 21: 36Z", "mfaAuthenticated": "true" } } }, "eventTime": "2023-09-06T01: 53: 19Z", "eventSource": "ec2-instance-connect.amazonaws.com", "eventName": "SendSSHPublicKey", "awsRegion": "ap-northeast-1", "sourceIPAddress": "10...", "userAgent": "Mozilla/5.0", "requestParameters": { "instanceId": "i-02...", "instanceOSUser": "ec2-user", "sSHPublicKey": "ssh-ed25519 AAAA..." }, "responseElements": { "requestId": "f84e...", "success": true }, "requestID": "f84e...", "eventID": "cdc5...", "readOnly": false, "eventType": "AwsApiCall", "managementEvent": true, "recipientAccountId": "1234...", "eventCategory": "Management", "tlsDetails": { "tlsVersion": "TLSv1.3", "cipherSuite": "TLS_AES_128_GCM_SHA256", "clientProvidedHostHeader": "ec2-instance-connect.ap-northeast-1.amazonaws.com" }, "sessionCredentialFromConsole": "true" } }
4. Linuxインスタンスにマネジメントコンソール上のEC2 Instance Connect(Endpointあり)で接続する場合
Linuxインスタンスにマネジメントコンソール上のEC2 Instance Connectで接続した場合、CloudTrailイベント履歴には SendSSHPublicKey イベントとOpenTunnelイベントが記録されます。
EC2 Instance Connectは、内部でSSH接続を利用しています。具体的には、Instance Connect APIからSSHのパブリックキーがインスタンスメタデータに送信されます。
EC2 Instance Connect を使用してインスタンスに接続すると、Instance Connect API から SSH パブリックキーがインスタンスメタデータにプッシュされ、60 秒間保持されます。
また、AWSサービスとEC2インスタンスとの間にOpenTunnelイベントでWebSocket接続を確立します。 こちらの動作が、CloudTrailイベント履歴にも記録されたということですね。
イベント履歴は、Pythonの辞書型データに加工されて取得できます。ローカルのSSH公開鍵を、EC2インスタンスに送信していることがわかりますね。
{ "EventId": "a0a9...", "EventName": "SendSSHPublicKey", "ReadOnly": "false", "AccessKeyId": "ASIA...", "EventTime": datetime.datetime(2023,10,12,16,52,18, tzinfo=tzlocal()), "EventSource": "ec2-instance-connect.amazonaws.com", "Username": "username", "Resources": [ { "ResourceType": "AWS::EC2::Instance", "ResourceName": "i-0d75..." } ], "CloudTrailEvent": '{ "eventVersion": "1.08", "userIdentity": { "type": "AssumedRole", "principalId": "AROA...:username", "arn": "arn:aws:sts::1234...:assumed-role/username/username", "accountId": "1234...", "accessKeyId": "ASIA...", "sessionContext": { "sessionIssuer": { "type": "Role", "principalId": "AROA...", "arn": "arn:aws:iam::1234...:role/username", "accountId": "1234...", "userName": "username" }, "webIdFederationData": {}, "attributes": { "creationDate": "2023-10-12T06:53:19Z", "mfaAuthenticated": "true" } } }, "eventTime": "2023-10-12T07:52:18Z", "eventSource": "ec2-instance-connect.amazonaws.com", "eventName": "SendSSHPublicKey", "awsRegion": "ap-northeast-1", "sourceIPAddress": "10...", "userAgent": "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/117.0.0.0 Safari/537.36", "requestParameters": { "instanceId": "i-0d75...", "instanceOSUser": "ec2-user", "sSHPublicKey": "ssh-ed25519 AAAA..." }, "responseElements": { "requestId": "ee95e...", "success": true }, "requestID": "ee95e...", "eventID": "a0a9...", "readOnly": false, "eventType": "AwsApiCall", "managementEvent": true, "recipientAccountId": "1234...", "eventCategory": "Management", "tlsDetails": { "tlsVersion": "TLSv1.3", "cipherSuite": "TLS_AES_128_GCM_SHA256", "clientProvidedHostHeader": "ec2-instance-connect.ap-northeast-1.amazonaws.com" }, "sessionCredentialFromConsole": "true" }', }
{ "EventId": "9947...", "EventName": "OpenTunnel", "ReadOnly": "false", "AccessKeyId": "ASIA...", "EventTime": datetime.datetime(2023,10,12,16,52,18, tzinfo=tzlocal()), "EventSource": "ec2-instance-connect.amazonaws.com", "Username": "username", "Resources": [], "CloudTrailEvent": '{ "eventVersion": "1.08", "userIdentity": { "type": "AssumedRole", "principalId": "AROA...:username", "arn": "arn:aws:sts::1234...:assumed-role/username/username", "accountId": "1234...", "accessKeyId": "ASIA...", "userName": "" }, "eventTime": "2023-10-12T07:52:18Z", "eventSource": "ec2-instance-connect.amazonaws.com", "eventName": "OpenTunnel", "awsRegion": "ap-northeast-1", "sourceIPAddress": "10...", "userAgent": "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/117.0.0.0 Safari/537.36", "requestParameters": { "instanceConnectEndpointId": "eice-0c78...", "maxTunnelDuration": "3600", "remotePort": "22", "privateIpAddress": "10..." }, "responseElements": null, "requestID": "bd7b...", "eventID": "9947...", "readOnly": false, "resources": [ { "accountId": "1234...", "type": "AWS::EC2::InstanceConnectEndpoint", "ARN": "arn:aws:ec2:ap-northeast-1:1234...:instance-connect-endpoint/eice-0c78..." } ], "eventType": "AwsApiCall", "managementEvent": true, "recipientAccountId": "1234...", "eventCategory": "Management" }', }
5. LinuxインスタンスにAWS CLIのSession Managerで接続する場合
LinuxインスタンスにAWS CLIのSession Managerで接続した場合、CloudTrailイベント履歴にはStartSessionイベント、CreateDataChannelイベント、OpenDataChannelイベントが記録されます。
こちらは、ssmmessages:CreateDataChannel
やssmmessages:OpenDataChannel
の言及があるこちらのリファレンスから読み取れます。
このエンドポイントは、クラウド内の Session Manager サービスでセッションチャネルを作成および削除するために必要です。
推測ですが、AWS CLIから接続する際には、マネジメントコンソールがやってくれていたCreateDataChannel
やOpenDataChannel
もAWS CLIが実行すると考えています。マネジメントコンソールからSessionManagerを使用するときと比べて、やることが多いのかもしれません。
AWS CLI上のコマンドは次の通りです。ここで、AWS CLIのプロファイルやEC2インスタンスのSession Manager設定は済んでいるものとします。
$ aws ssm start-session --target i-03... --region ap-northeast-1 --profile onoyan
イベント履歴は、Pythonの辞書型データに加工されて取得できます。
{ "EventId": "fe52...", "EventName": "StartSession", "ReadOnly": "false", "AccessKeyId": "ASIA...", "EventTime": datetime.datetime(2023,9,7,16,50,54, tzinfo=tzlocal()), "EventSource": "ssm.amazonaws.com", "Username": "botocore-session-16...", "Resources": [], "CloudTrailEvent": { "eventVersion": "1.08", "userIdentity": { "type": "AssumedRole", "principalId": "AROA...", "arn": "arn:aws:sts: : 1234...:assumed-role/cm.../botocore-session-16...", "accountId": "1234...", "accessKeyId": "ASIA...", "sessionContext": { "sessionIssuer": { "type": "Role", "principalId": "AROA...", "arn": "arn:aws:iam: : 1234...:role/cm...", "accountId": "1234...", "userName": "cm..." }, "attributes": { "creationDate": "2023-09-07T07: 18: 26Z", "mfaAuthenticated": "false" } } }, "eventTime": "2023-09-07T07: 50: 54Z", "eventSource": "ssm.amazonaws.com", "eventName": "StartSession", "awsRegion": "ap-northeast-1", "sourceIPAddress": "10...", "userAgent": "aws-cli/2.13.15 Python/3.11.4 Darwin/22.5.0 exe/x86_64 prompt/off command/ssm.start-session", "requestParameters": { "target": "i-03..." }, "responseElements": { "sessionId": "botocore-session-16...", "tokenValue": "Value hidden due to security reasons.", "streamUrl": "wss: //ssmmessages.ap-northeast-1.amazonaws.com/v1/data-channel..." }, "requestID": "9c0b...", "eventID": "fe52...", "readOnly": false, "eventType": "AwsApiCall", "managementEvent": true, "recipientAccountId": "1234...", "eventCategory": "Management", "tlsDetails": { "tlsVersion": "TLSv1.2", "cipherSuite": "ECDHE-RSA-AES128-GCM-SHA256", "clientProvidedHostHeader": "ssm.ap-northeast-1.amazonaws.com" } } }
{ "EventId": "cfd4...", "EventName": "CreateDataChannel", "ReadOnly": "false", "AccessKeyId": "ASIA...", "EventTime": datetime.datetime(2023,9,7,16,50,54, tzinfo=tzlocal()), "EventSource": "ssm.amazonaws.com", "Username": "i-03...", "Resources": [], "CloudTrailEvent": { "eventVersion": "1.08", "userIdentity": { "type": "AssumedRole", "principalId": "AROA...", "arn": "arn:aws:sts: : 1234...:assumed-role/AmazonSSMManagedInstanceCore/i-03...", "accountId": "1234...", "accessKeyId": "ASIA...", "sessionContext": { "sessionIssuer": { "type": "Role", "principalId": "AROA...", "arn": "arn:aws:iam: : 1234...:role/AmazonSSMManagedInstanceCore", "accountId": "1234...", "userName": "AmazonSSMManagedInstanceCore" }, "attributes": { "creationDate": "2023-09-07T07: 41: 39Z", "mfaAuthenticated": "false" }, "ec2RoleDelivery": "2.0" } }, "eventTime": "2023-09-07T07: 50: 54Z", "eventSource": "ssm.amazonaws.com", "eventName": "CreateDataChannel", "awsRegion": "ap-northeast-1", "sourceIPAddress": "13...", "userAgent": "Go-http-client/1.1", "requestParameters": { "messageSchemaVersion": "1.0", "requestId": "11fb...", "sessionId": "botocore-session-16...", "clientId": "" }, "responseElements": { "messageSchemaVersion": "1.0", "tokenValue": "Value hidden due to security reasons." }, "requestID": "e209...", "eventID": "cfd4...", "readOnly": false, "eventType": "AwsApiCall", "managementEvent": true, "recipientAccountId": "1234...", "eventCategory": "Management", "tlsDetails": { "clientProvidedHostHeader": "ssmmessages.ap-northeast-1.amazonaws.com" } } }
{ "EventId": "6eda...", "EventName": "OpenDataChannel", "ReadOnly": "false", "EventTime": datetime.datetime(2023,9,7,16,50,56, tzinfo=tzlocal()), "EventSource": "ssm.amazonaws.com", "Resources": [], "CloudTrailEvent": { "eventVersion": "1.08", "userIdentity": { "accountId": "1234..." }, "eventTime": "2023-09-07T07: 50: 56Z", "eventSource": "ssm.amazonaws.com", "eventName": "OpenDataChannel", "awsRegion": "ap-northeast-1", "sourceIPAddress": "10...", "userAgent": "ssm.amazonaws.com", "requestParameters": { "sessionId": "botocore-session-16..." }, "responseElements": null, "requestID": "cf3f...", "eventID": "6edf...", "readOnly": false, "eventType": "AwsApiCall", "managementEvent": true, "recipientAccountId": "1234...", "eventCategory": "Management" } }
6. LinuxインスタンスにAWS CLIのEC2 Instance Connect(Endopintなし)で接続する場合
LinuxインスタンスにAWS CLIのEC2 Instance Connect(Endpointなし)で接続した場合、CloudTrailイベント履歴にはSendSSHPublicKeyイベントが記録されます。
EC2 Instance Connectは、裏でSSH接続を行っていました。そのため、SendSSHPublicKey
イベントが記録されています。
AWS CLI上のコマンドは次の通りです。ここで、AWS CLIのプロファイルやEC2インスタンスのInstance Connect設定は済んでいるものとします。
$ aws ec2-instance-connect ssh --instance-id i-0a... --connection-type eice --profile onoyan
イベント履歴は、Pythonの辞書型データに加工されて取得できます。
{ "EventId": "6111...", "EventName": "SendSSHPublicKey", "ReadOnly": "false", "AccessKeyId": "ASIA...", "EventTime": datetime.datetime(2023,10,12,15,58,49, tzinfo=tzlocal()), "EventSource": "ec2-instance-connect.amazonaws.com", "Username": "username", "Resources": [ { "ResourceType": "AWS::EC2::Instance", "ResourceName": "i-0d75..." } ], "CloudTrailEvent": '{ "eventVersion": "1.08", "userIdentity": { "type": "AssumedRole", "principalId": "AROA...:username", "arn": "arn:aws:sts::1234...:assumed-role/username/username", "accountId": "1234...", "accessKeyId": "ASIA...", "sessionContext": { "sessionIssuer": { "type": "Role", "principalId": "AROA...", "arn": "arn:aws:iam::1234...:role/username", "accountId": "1234...", "userName": "username" }, "webIdFederationData": {}, "attributes": { "creationDate": "2023-10-12T06:53:19Z", "mfaAuthenticated": "true" } } }, "eventTime": "2023-10-12T06:58:49Z", "eventSource": "ec2-instance-connect.amazonaws.com", "eventName": "SendSSHPublicKey", "awsRegion": "ap-northeast-1", "sourceIPAddress": "10...", "userAgent": "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/117.0.0.0 Safari/537.36", "requestParameters": { "instanceId": "i-0d75...", "instanceOSUser": "ec2-user", "sSHPublicKey": "ssh-ed25519 AAAA..." }, "responseElements": { "requestId": "1c3f...", "success": true }, "requestID": "1c3fe...", "eventID": "6111...", "readOnly": false, "eventType": "AwsApiCall", "managementEvent": true, "recipientAccountId": "1234...", "eventCategory": "Management", "tlsDetails": { "tlsVersion": "TLSv1.3", "cipherSuite": "TLS_AES_128_GCM_SHA256", "clientProvidedHostHeader": "ec2-instance-connect.ap-northeast-1.amazonaws.com" }, "sessionCredentialFromConsole": "true" }', }
7. LinuxインスタンスにAWS CLIのEC2 Instance Connect(Endopintあり)で接続する場合
LinuxインスタンスにAWS CLIのEC2 Instance Connect(Endpointなし)で接続した場合、CloudTrailイベント履歴にはSendSSHPublicKeyイベントとOpenTunnelイベントが記録されます。
OpenTunnel
に関しては、こちらのリファレンスに記載があります。
SSH を使用して Linux インスタンスに接続し、
open-tunnel
コマンドを使用してプライベートトンネルを確立できます。open-tunnel
はシングル接続またはマルチ接続モードで使用できます
EC2 Instance Connectは、裏でSSH接続を行っていました。そのため、SendSSHPublicKey
イベントが記録されています。今回はそれに加えてAWS CLIの処理も含まれています。そのため、こちらのopen-tunnel
コマンドがイベント履歴にも記録されているのだと思われます。
AWS CLI上のコマンドは次の通りです。ここで、AWS CLIのプロファイルやEC2インスタンスのInstance Connect設定は済んでいるものとします。
$ aws ec2-instance-connect ssh --instance-id i-0a... --connection-type eice --profile onoyan
イベント履歴は、Pythonの辞書型データに加工されて取得できます。
{ "EventId": "4fad...", "EventName": "SendSSHPublicKey", "ReadOnly": "false", "AccessKeyId": "ASIA...", "EventTime": datetime.datetime(2023,9,7,16,33,17, tzinfo=tzlocal()), "EventSource": "ec2-instance-connect.amazonaws.com", "Username": "botocore-session-16...", "Resources": [ { "ResourceType": "AWS::EC2::Instance", "ResourceName": "i-0a..." } ], "CloudTrailEvent": { "eventVersion": "1.08", "userIdentity": { "type": "AssumedRole", "principalId": "AROA...", "arn": "arn:aws:sts: : 1234...:assumed-role/cm.../botocore-session-16...", "accountId": "1234...", "accessKeyId": "ASIA...", "sessionContext": { "sessionIssuer": { "type": "Role", "principalId": "AROA...", "arn": "arn:aws:iam: : 1234...:role/cm...", "accountId": "1234...", "userName": "cm..." }, "webIdFederationData": {}, "attributes": { "creationDate": "2023-09-07T07: 18: 26Z", "mfaAuthenticated": "false" } } }, "eventTime": "2023-09-07T07: 33: 17Z", "eventSource": "ec2-instance-connect.amazonaws.com", "eventName": "SendSSHPublicKey", "awsRegion": "ap-northeast-1", "sourceIPAddress": "10...", "userAgent": "aws-cli/2.13.15 Python/3.11.4 Darwin/22.5.0 exe/x86_64 prompt/off command/ec2-instance-connect.ssh", "requestParameters": { "instanceId": "i-0a...", "instanceOSUser": "ec2-user", "sSHPublicKey": "ssh-ed25519 AA..." }, "responseElements": { "requestId": "5298...", "success": true }, "requestID": "5298...", "eventID": "4fad...", "readOnly": false, "eventType": "AwsApiCall", "managementEvent": true, "recipientAccountId": "1234...", "eventCategory": "Management", "tlsDetails": { "tlsVersion": "TLSv1.3", "cipherSuite": "TLS_AES_128_GCM_SHA256", "clientProvidedHostHeader": "ec2-instance-connect.ap-northeast-1.amazonaws.com" } } }
{ "EventId": "e966...", "EventName": "OpenTunnel", "ReadOnly": "false", "AccessKeyId": "ASIA...", "EventTime": datetime.datetime(2023,9,7,16,33,18, tzinfo=tzlocal()), "EventSource": "ec2-instance-connect.amazonaws.com", "Username": "botocore-session-16...", "Resources": [], "CloudTrailEvent": { "eventVersion": "1.08", "userIdentity": { "type": "AssumedRole", "principalId": "AROA...", "arn": "arn:aws:sts: : 1234...:assumed-role/cm.../botocore-session-16...", "accountId": "1234...", "accessKeyId": "ASIA...", "userName": "" }, "eventTime": "2023-09-07T07: 33: 18Z", "eventSource": "ec2-instance-connect.amazonaws.com", "eventName": "OpenTunnel", "awsRegion": "ap-northeast-1", "sourceIPAddress": "10...", "userAgent": "aws-cli/2.13.15 Python/3.11.4 Darwin/22.5.0 exe/x86_64 prompt/off command/ec2-instance-connect.open-tunnel", "requestParameters": { "instanceConnectEndpointId": "eice-0e...", "maxTunnelDuration": "3600", "remotePort": "1", "privateIpAddress": "10..." }, "responseElements": null, "requestID": "3004...", "eventID": "e966...", "readOnly": false, "resources": [ { "accountId": "1234...", "type": "AWS: :EC2: :InstanceConnectEndpoint", "ARN": "arn:aws:ec2:ap-northeast-1: 1234...:instance-connect-endpoint/eice-0e..." } ], "eventType": "AwsApiCall", "managementEvent": true, "recipientAccountId": "1234...", "eventCategory": "Management" } }
8. Windowsインスタンスにマネジメントコンソール上のSession Managerで接続する場合
Windowsインスタンスにマネジメントコンソール上のSession Managerで接続した場合、CloudTrailイベント履歴にはStartSessionイベント、CreateDataChannelイベント、OpenDataChannelイベントが記録されます。
こちらは、上述したSession Managerでのイベント発火と同じくStartSession
, CreateDataChannel
, OpenDataChannel
が記録されていますね。
イベント履歴は、Pythonの辞書型データに加工されて取得できます。LinuxインスタンスにAWS CLIのSession Managerで接続した場合と同じイベントが発火しています。
{ "EventId": "d9da...", "EventName": "StartSession", "ReadOnly": "false", "AccessKeyId": "ASIA...", "EventTime": datetime.datetime(2023,9,7,17,9,52, tzinfo=tzlocal()), "EventSource": "ssm.amazonaws.com", "Username": "cm...", "Resources": [], "CloudTrailEvent": { "eventVersion": "1.08", "userIdentity": { "type": "AssumedRole", "principalId": "AROA...", "arn": "arn:aws:sts: : 1234...:assumed-role/cm.../cm...", "accountId": "1234...", "accessKeyId": "ASIA...", "sessionContext": { "sessionIssuer": { "type": "Role", "principalId": "AROA...", "arn": "arn:aws:iam: : 1234...:role/cm...", "accountId": "1234...", "userName": "cm..." }, "attributes": { "creationDate": "2023-09-07T07: 36: 11Z", "mfaAuthenticated": "true" } } }, "eventTime": "2023-09-07T08: 09: 52Z", "eventSource": "ssm.amazonaws.com", "eventName": "StartSession", "awsRegion": "ap-northeast-1", "sourceIPAddress": "10...", "userAgent": "AWS Internal", "requestParameters": { "target": "i-0f..." }, "responseElements": { "sessionId": "cm...", "tokenValue": "Value hidden due to security reasons.", "streamUrl": "wss: //ssmmessages.ap-northeast-1.amazonaws.com/v1/data-channel..." }, "requestID": "9cc8...", "eventID": "d9da...", "readOnly": false, "eventType": "AwsApiCall", "managementEvent": true, "recipientAccountId": "1234...", "eventCategory": "Management", "sessionCredentialFromConsole": "true" } }
{ "EventId": "d7cb...", "EventName": "CreateDataChannel", "ReadOnly": "false", "AccessKeyId": "ASIA...", "EventTime": datetime.datetime(2023,9,7,17,9,54, tzinfo=tzlocal()), "EventSource": "ssm.amazonaws.com", "Username": "i-0f...", "Resources": [], "CloudTrailEvent": { "eventVersion": "1.08", "userIdentity": { "type": "AssumedRole", "principalId": "AROA...", "arn": "arn:aws:sts: : 1234...:assumed-role/AmazonSSMManagedInstanceCore/i-0f...", "accountId": "1234...", "accessKeyId": "ASIA...", "sessionContext": { "sessionIssuer": { "type": "Role", "principalId": "AROA...", "arn": "arn:aws:iam: : 1234...:role/AmazonSSMManagedInstanceCore", "accountId": "1234...", "userName": "AmazonSSMManagedInstanceCore" }, "attributes": { "creationDate": "2023-09-07T08: 05: 55Z", "mfaAuthenticated": "false" }, "ec2RoleDelivery": "2.0" } }, "eventTime": "2023-09-07T08: 09: 54Z", "eventSource": "ssm.amazonaws.com", "eventName": "CreateDataChannel", "awsRegion": "ap-northeast-1", "sourceIPAddress": "10...", "userAgent": "Go-http-client/1.1", "requestParameters": { "messageSchemaVersion": "1.0", "requestId": "a4e...", "sessionId": "cm...", "clientId": "" }, "responseElements": { "messageSchemaVersion": "1.0", "tokenValue": "Value hidden due to security reasons." }, "requestID": "155b...", "eventID": "d7cb...", "readOnly": false, "eventType": "AwsApiCall", "managementEvent": true, "recipientAccountId": "1234...", "eventCategory": "Management", "tlsDetails": { "clientProvidedHostHeader": "ssmmessages.ap-northeast-1.amazonaws.com" } } }
{ "EventId": "a8a9...", "EventName": "OpenDataChannel", "ReadOnly": "false", "EventTime": datetime.datetime(2023,9,7,17,9,52, tzinfo=tzlocal()), "EventSource": "ssm.amazonaws.com", "Resources": [], "CloudTrailEvent": { "eventVersion": "1.08", "userIdentity": { "accountId": "1234..." }, "eventTime": "2023-09-07T08: 09: 52Z", "eventSource": "ssm.amazonaws.com", "eventName": "OpenDataChannel", "awsRegion": "ap-northeast-1", "sourceIPAddress": "10...", "userAgent": "ssm.amazonaws.com", "requestParameters": { "sessionId": "cm..." }, "responseElements": null, "requestID": "cbce...", "eventID": "a8a9...", "readOnly": false, "eventType": "AwsApiCall", "managementEvent": true, "recipientAccountId": "1234...", "eventCategory": "Management" } }
9. Windowsインスタンスにマネジメントコンソール上のFleet Managerで接続する場合
Windowsインスタンスにマネジメントコンソール上のEC2 Instance Connectで接続した場合、CloudTrailイベント履歴には StartSession、StartConnection、OpenDataChannel、CreateDataChannelと、さまざまなイベントが乱立しています。
これまでの接続方法と比べると、多くのイベントが続けて実行されるのが特徴的です。Fleet ManagerではWindowsのGUIデスクトップにマネコンからリモートで接続できるため、EC2内で処理されるイベントも多くなっていますね。
それでも、イベント自体は上述のSession Managerで見られたような処理が実行されています。Fleet Manager自体がマネジメントコンソール上のSystems Managerで利用可能なので、裏側ではSession Managerと同じような処理を行っていると考えられます。
イベント履歴は、Pythonの辞書型データに加工されて取得できます。
{ "EventId": "c652...", "EventName": "StartSession", "ReadOnly": "false", "AccessKeyId": "ASIA...", "EventTime": datetime.datetime(2023,9,7,10,59,24, tzinfo=tzlocal()), "EventSource": "ssm.amazonaws.com", "Username": "cm...", "Resources": [], "CloudTrailEvent": { "eventVersion": "1.08", "userIdentity": { "type": "AssumedRole", "principalId": "AROA...", "arn": "arn:aws:sts: : 1234...:assumed-role/cm...", "accountId": "1234...", "accessKeyId": "ASIA...", "sessionContext": { "sessionIssuer": { "type": "Role", "principalId": "AROA...", "arn": "arn:aws:iam: : 1234...:role/cm...", "accountId": "1234...", "userName": "cm..." }, "attributes": { "creationDate": "2023-09-07T01: 04: 06Z", "mfaAuthenticated": "true" } }, "invokedBy": "ssm-guiconnect.amazonaws.com" }, "eventTime": "2023-09-07T01: 59: 24Z", "eventSource": "ssm.amazonaws.com", "eventName": "StartSession", "awsRegion": "ap-northeast-1", "sourceIPAddress": "ssm-guiconnect.amazonaws.com", "userAgent": "AWS Internal", "requestParameters": { "target": "i-07...", "documentName": "AWS-StartPortForwardingSession", "reason": "Used for SSM Fleet Manager Remote Desktop", "parameters": { "localPortNumber": [ "9" ], "portNumber": [ "3" ] } }, "responseElements": { "sessionId": "cm...", "tokenValue": "Value hidden due to security reasons.", "streamUrl": "wss: //ssmmessages.ap-northeast-1.amazonaws.com/v1/data-channel..." }, "requestID": "e4a5...", "eventID": "c652...", "readOnly": false, "eventType": "AwsApiCall", "managementEvent": true, "recipientAccountId": "1234...", "eventCategory": "Management", "sessionCredentialFromConsole": "true" } }
{ "EventId": "2921...", "EventName": "StartConnection", "ReadOnly": "false", "AccessKeyId": "ASIA.", "EventTime": datetime.datetime(2023,9,7,10,59,24, tzinfo=tzlocal()), "EventSource": "ssm-guiconnect.amazonaws.com", "Username": "cm...", "Resources": [], "CloudTrailEvent": { "eventVersion": "1.08", "userIdentity": { "type": "AssumedRole", "principalId": "AROA...", "arn": "arn:aws:sts: : 1234...:assumed-role/cm...", "accountId": "1234...", "accessKeyId": "ASIA...", "sessionContext": { "sessionIssuer": { "type": "Role", "principalId": "AROA...", "arn": "arn:aws:iam: : 1234...:role/cm...", "accountId": "1234...", "userName": "cm..." }, "webIdFederationData": {}, "attributes": { "creationDate": "2023-09-07T01: 04: 06Z", "mfaAuthenticated": "true" } } }, "eventTime": "2023-09-07T01: 59: 24Z", "eventSource": "ssm-guiconnect.amazonaws.com", "eventName": "StartConnection", "awsRegion": "ap-northeast-1", "sourceIPAddress": "10...", "userAgent": "aws-internal/3 aws-sdk-java/1.12.479 Linux/5.10.186-157.751.amzn2int.x86_64 OpenJDK_64-Bit_Server_VM/25.372-b08 java/1.8.0_372 vendor/Oracle_Corporation cfg/retry-mode/standard", "requestParameters": { "ConnectionParameters": { "SupportGraphicsPipeline": true }, "AuthType": "Credentials", "Protocol": "RDP", "ConnectionType": "SessionManager", "InstanceId": "i-07" }, "responseElements": { "ConnectionArn": "arn:aws:ssm-guiconnect:ap-northeast-1: 1234...:connection/1e9d...", "ConnectionKey": "e1a8...", "ClientToken": "c559...", "requestId": "9556..." }, "requestID": "9556...", "eventID": "2921...", "readOnly": false, "eventType": "AwsApiCall", "managementEvent": true, "recipientAccountId": "1234", "eventCategory": "Management" } }
{ "EventId": "707a...", "EventName": "OpenDataChannel", "ReadOnly": "false", "EventTime": datetime.datetime(2023,9,7,10,59,25, tzinfo=tzlocal()), "EventSource": "ssm.amazonaws.com", "Resources": [], "CloudTrailEvent": { "eventVersion": "1.08", "userIdentity": { "accountId": "1234" }, "eventTime": "2023-09-07T01: 59: 25Z", "eventSource": "ssm.amazonaws.com", "eventName": "OpenDataChannel", "awsRegion": "ap-northeast-1", "sourceIPAddress": "AWS Internal", "userAgent": "ssm.amazonaws.com", "requestParameters": { "sessionId": "cm..." }, "responseElements": null, "requestID": "9f09...", "eventID": "707a...", "readOnly": false, "eventType": "AwsApiCall", "managementEvent": true, "recipientAccountId": "1234...", "eventCategory": "Management" } }
{ "EventId": "dd82...", "EventName": "CreateDataChannel", "ReadOnly": "false", "AccessKeyId": "ASIA...", "EventTime": datetime.datetime(2023,9,7,10,59,26, tzinfo=tzlocal()), "EventSource": "ssm.amazonaws.com", "Username": "i-07...", "Resources": [], "CloudTrailEvent": { "eventVersion": "1.08", "userIdentity": { "type": "AssumedRole", "principalId": "AROA...", "arn": "arn:aws:sts: : 1234...:assumed-role/AmazonSSMManagedInstanceCore/i-07...", "accountId": "1234...", "accessKeyId": "ASIA...", "sessionContext": { "sessionIssuer": { "type": "Role", "principalId": "AROA...", "arn": "arn:aws:iam: : 1234...:role/AmazonSSMManagedInstanceCore", "accountId": "1234...", "userName": "AmazonSSMManagedInstanceCore" }, "attributes": { "creationDate": "2023-09-07T01: 48: 52Z", "mfaAuthenticated": "false" }, "ec2RoleDelivery": "2.0" } }, "eventTime": "2023-09-07T01: 59: 26Z", "eventSource": "ssm.amazonaws.com", "eventName": "CreateDataChannel", "awsRegion": "ap-northeast-1", "sourceIPAddress": "10...", "userAgent": "Go-http-client/1.1", "requestParameters": { "messageSchemaVersion": "1.0", "requestId": "59a2...", "sessionId": "cm...", "clientId": "" }, "responseElements": { "messageSchemaVersion": "1.0", "tokenValue": "Value hidden due to security reasons." }, "requestID": "ae7f...", "eventID": "dd82...", "readOnly": false, "eventType": "AwsApiCall", "managementEvent": true, "recipientAccountId": "1234...", "vpcEndpointId": "vpce-03...", "eventCategory": "Management", "tlsDetails": { "clientProvidedHostHeader": "ssmmessages.ap-northeast-1.amazonaws.com" } } }
10. WindowsインスタンスにAWS CLIのInstance Connectで接続する場合
WindowsインスタンスにAWS CLIのInstance Connectで接続した場合、CloudTrailイベント履歴にはOpenTunnelイベントが取得されます。
「5. LinuxインスタンスにAWS CLIのEC2 Instance Connectで接続する場合」で述べたように、今回はAWS CLIのopen-tunnel
コマンドがイベント履歴に記録されているのだと思われます。
また、LinuxインスタンスにInstance Connectで接続する際には、裏側でSSH接続を行っていました。しかし今回はWindowsインスタンスに接続するため、裏側ではRDP接続の処理が走ります。こういった流れがあって、SendSSHPublicKey
のようなイベントは記録されない、ということが読み取れます。
AWS CLI上のコマンドは次の通りです。ここで、AWS CLIのプロファイルやEC2インスタンスのInstance Connect設定は済んでいるものとします。
$ aws ec2-instance-connect open-tunnel \ --instance-connect-endpoint-id eice-06... \ --private-ip-address 10.0... \ --local-port 13389 \ --remote-port 3389 \ --profile onoyan
イベント履歴は、Pythonの辞書型データに加工されて取得できます。
{ "EventId": "da6f...", "EventName": "OpenTunnel", "ReadOnly": "false", "AccessKeyId": "ASIA...", "EventTime": datetime.datetime(2023,9,19,14,12,7, tzinfo=tzlocal()), "EventSource": "ec2-instance-connect.amazonaws.com", "Username": "botocore-session-1695...", "Resources": [], "CloudTrailEvent": '{ "eventVersion": "1.08", "userIdentity": { "type": "AssumedRole", "principalId": "AROA...", "arn": "arn:aws:sts::2459...:assumed-role/cm-onoyama.shodai/botocore-session-1695...", "accountId": "2459...", "accessKeyId": "ASIA...", "userName": "" }, "eventTime": "2023-09-19T05:12:07Z", "eventSource": "ec2-instance-connect.amazonaws.com", "eventName": "OpenTunnel", "awsRegion": "ap-northeast-1", "sourceIPAddress": "10.10...", "userAgent": "aws-cli/2.13.15 Python/3.11.4 Darwin/22.5.0 exe/x86_64 prompt/off command/ec2-instance-connect.open-tunnel", "requestParameters": { "instanceConnectEndpointId": "eice-06...", "maxTunnelDuration": "3600", "remotePort": "3389", "privateIpAddress": "10.10..." }, "responseElements": null, "requestID": "909e...", "eventID": "da6f...", "readOnly": false, "resources": [ { "accountId": "2459...", "type": "AWS::EC2::InstanceConnectEndpoint", "ARN": "arn:aws:ec2:ap-northeast-1:2459...:instance-connect-endpoint/eice-06..." } ], "eventType": "AwsApiCall", "managementEvent": true, "recipientAccountId": "2459...", "eventCategory": "Management" }', }
さいごに
EC2の接続方法は他にもありますので、今回の検証結果には検証の余地はあります。
それでもEC2への接続方法によって、記録されるイベント履歴が変わることが分かりました。AWS CLIとマネジメントコンソールとでは、必要なAPIが異なります。また、Session ManagerやInstance Connectでは接続の仕組みも違ってきます。
EC2に何かしらの不具合が生じて、ClouTrailのイベント履歴を見る必要が出てきた際は、これらのイベントを重点的に探すといいでしょう。効率的に原因を特定できるかもしれません。では!